package com.letoo.dragon.dataaccess.dao.cahce.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.stereotype.Repository;

import com.letoo.dragon.dataaccess.dao.cahce.SystemCodeCacheDAO;
import com.letoo.dragon.dataaccess.domain.dbo.SystemCodeDO;

@Repository("systemCodeCacheDAO")
public class SystemCodeCacheDAOImpl extends BaseCacheDAOImpl implements SystemCodeCacheDAO {
    public static String PREFIX_SYSTEM_CODE = "systemCode:";

    @Override
    public boolean addSystemCode(final SystemCodeDO systemCode) {
        boolean result = getRedisTemplate().execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) {
                String key = PREFIX_SYSTEM_CODE + systemCode.getCodeType();
                connection.zAdd(serialize(key), systemCode.getOrderNo(), serialize(systemCode));
                return true;
            }
        });

        return result;
    }

    @Override
    public boolean batchAddSystemCode(final List<SystemCodeDO> systemCodeList, final boolean isInit) {
        boolean result = getRedisTemplate().execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) {
                if (isInit) {
                    for (SystemCodeDO systemCode : systemCodeList) {
                        String key = PREFIX_SYSTEM_CODE + systemCode.getCodeType();
                        connection.del(serialize(key));
                    }

                    for (SystemCodeDO systemCode : systemCodeList) {
                        String key = PREFIX_SYSTEM_CODE + systemCode.getCodeType();
                        connection.zAdd(serialize(key), systemCode.getOrderNo(), serialize(systemCode));
                    }
                } else {
                    for (SystemCodeDO systemCode : systemCodeList) {
                        String key = PREFIX_SYSTEM_CODE + systemCode.getCodeType();
                        connection.zAdd(serialize(key), systemCode.getOrderNo(), serialize(systemCode));
                    }
                }

                return true;
            }
        }, false, true);

        return result;
    }

    @Override
    public boolean updateSystemCode(final SystemCodeDO oldSystemCode, final SystemCodeDO newSystemCode) {
        boolean result = getRedisTemplate().execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) {
                String oldKey = PREFIX_SYSTEM_CODE + oldSystemCode.getCodeType();
                connection.zRem(serialize(oldKey), serialize(oldSystemCode));
                String newKey = PREFIX_SYSTEM_CODE + newSystemCode.getCodeType();
                connection.zAdd(serialize(newKey), newSystemCode.getOrderNo(), serialize(newSystemCode));

                return true;
            }
        });

        return result;
    }

    @Override
    public List<SystemCodeDO> getSystemCodes(final String codeType) {
        List<SystemCodeDO> result = getRedisTemplate().execute(new RedisCallback<List<SystemCodeDO>>() {
            @Override
            public List<SystemCodeDO> doInRedis(RedisConnection connection) {
                String key = PREFIX_SYSTEM_CODE + codeType;
                Set<byte[]> byteSet = connection.zRange(serialize(key), 0, -1);
                List<SystemCodeDO> systemCodes = new ArrayList<SystemCodeDO>();

                for (byte[] bytes : byteSet) {
                    SystemCodeDO systemCode = deserialize(SystemCodeDO.class, bytes);
                    if (systemCode != null) {
                        systemCodes.add(systemCode);
                    }
                }

                return systemCodes;
            }
        });

        return result;
    }

}
